#include <stdio.h>
#include <stdlib.h>

typedef struct  Node{
	int data;
	struct Node* next;
}Node , *PNode;

void Insert_tail (int x , PNode* p)
{
	PNode temp1 = (PNode)malloc(sizeof(Node));
	temp1->data = x;
	PNode temp2 = *p;

	if ((*p) == NULL)
	{
		(*p) = temp1;
	}
	else
	{
		while (temp2->next != NULL)
		{
			temp2 = temp2->next;
		}
		temp2->next = temp1;
	}
	temp1->next = NULL;
}

void Print (PNode* temp)//这里传入的是头结点，head作为头结点，没有数据域和指针域，可以理解为一个单纯的指向节点的地址，存放的是下一个节点的地址
{
	PNode tem = (*temp);

	while (tem->next != NULL)
	{
		if (tem->next != NULL)
			printf ("%d " , tem->data);
		else
			printf ("%d" , tem->data);

		tem = tem->next;
	}
}

PNode merge (PNode *headA , PNode *headB)
{
	PNode A = (*headA);
	PNode B = (*headB);
	PNode head = (PNode)malloc(sizeof(Node));
	head->next = A;
	PNode pc = head;

	while(A&&B)
	{
		if (A->data <= B->data)
		{
			pc->next = A;
			pc = A;
			A = A->next;
		}
		else
		{
			pc->next = B;
			pc = B;
			B = B->next;
		}

	}
	pc->next = A?A:B;
	return head;
}

void Reverse (PNode *plist)
{
	PNode temp1 = (*plist);
	PNode temp2 , temp3 = NULL;
	while (temp1 != NULL)
	{
		temp2 = temp1->next;
		temp1->next = temp3;
		temp3 = temp1;

		temp1 = temp2;

	}
	(*plist) = temp3;
}

int main ()
{
	PNode headA = NULL;
	PNode headB = NULL;

	int n , m;
	scanf ("%d%d" , &n , &m);
	int tem;
	int tem1;
	for (int i = 0 ; i < n ; i++)
	{
		scanf ("%d" , &tem);
		Insert_tail(tem , &headA);
	}

	for (int i = 0 ; i < m ; i++)
	{
		scanf ("%d" , &tem1);
		Insert_tail(tem1 , &headB);
	}

	PNode plinkedlist = merge (&headA , &headB);

	Reverse(&plinkedlist);

	Print(&plinkedlist);




	return 0;
}